package com.sumec.service.impl;

import com.google.common.base.Joiner;
import com.sumec.dao.*;
import com.sumec.entity.*;
import com.sumec.service.IWorkSumService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Service
public class WorkSumserviceImpl implements IWorkSumService {
    private final static Logger log = LoggerFactory.getLogger(WorkSumserviceImpl.class);

    @Autowired
    private WorkEmpMapper workEmpMapper;
    @Autowired
    private WorkFlowSummaryMapper workFlowSummaryMapper;
    @Autowired
    private WorkHolidaySummaryMapper workHolidaySummaryMapper;
    @Autowired
    private WorkSignSummaryMapper workSignSummaryMapper;
    @Autowired
    private WorkTripSummaryMapper workTripSummaryMapper;
    @Autowired
    private WorkSummaryMapper workSummaryMapper;
    @Autowired
    private WorkReimburseSummaryMapper workReimburseSummaryMapper;
    @Autowired
    private WorkLearnSummaryMapper workLearnSummaryMapper;
    @Autowired
    private WorkDocReadSummaryMapper workDocReadSummaryMapper;

    @Override
    @Transactional
    public void initUserWorkSummary() {
        log.info("initUserWorkSummary开始");
        // 查询出所有人员
        List<WorkEmp> empList = workEmpMapper.findAll();
        log.info("总数据条数：" + empList.size());
        for (int i= 0; i < empList.size(); i++) {
            WorkEmp emp = empList.get(i);
            log.info("正在同步第" + i + "条数据，员工工号为：" + emp.getWorkCode());
            if (StringUtils.isEmpty(emp.getWorkCode())) {
                continue;
            }
            WorkSummary summary = new WorkSummary();
            // 基本信息
            summary.setAnnual(2021);
            summary.setWorkCode(emp.getWorkCode());
            summary.setUserName(emp.getUserName());

            String workCode = emp.getWorkCode();

            // 流程
            WorkFlowSummary flow = workFlowSummaryMapper.selectByWorkCode(workCode);
            summary.setFlowTotal(flow != null ? flow.getFlowTotal() : 0);
            summary.setFlowShortestTime(flow != null ? flow.getFlowShortestTime().setScale(2, RoundingMode.HALF_UP) : new BigDecimal(0));
            summary.setFlowAvgTime(flow != null ? flow.getFlowTime().divide(new BigDecimal(flow.getFlowTotal()), BigDecimal.ROUND_HALF_UP).setScale(2,RoundingMode.HALF_UP) : new BigDecimal(0));
            summary.setMostPeriod(flow != null ? flow.getMostPeriod() : "");

            // 年假
            WorkHolidaySummary holiday = workHolidaySummaryMapper.selectByWorkCode(workCode);
            summary.setAnnualLeave(holiday != null ? holiday.getAnnualLeave() : 0);
            summary.setHoliday(holiday != null ? holiday.getAnnualLeave() - holiday.getAbandonDay() : 0);

            // 考勤
            List<WorkSignSummary> signList = workSignSummaryMapper.listByWorkCode(workCode);
            if (signList != null && !signList.isEmpty()) {
                summary.setSignTotal(signList.size());
                String earliestsignInTime = workSignSummaryMapper.findEarliestSignInTime(workCode);
                String earliestSignInDate = workSignSummaryMapper.findEarliestSignInDate(workCode, earliestsignInTime);

                String latestsignOutTime = workSignSummaryMapper.findLatestSignOutTime(workCode);
                String latestsignOutDate = workSignSummaryMapper.findLatestSignOutDate(workCode, latestsignOutTime);
                summary.setEarliestSign(earliestSignInDate + " " + earliestsignInTime);
                summary.setLatestSign(latestsignOutDate + " " + latestsignOutTime);
            }

            // 差旅
            List<WorkTripSummary> tripList = workTripSummaryMapper.listByWorkCode(workCode);
            String cityStr = "";
            Float tripTotal = 0f;
            int tripCityNum = 0;
            if (tripList != null && !tripList.isEmpty()) {
                for (WorkTripSummary trip : tripList) {
                    tripTotal = tripTotal + trip.getTripDay().floatValue();
                    cityStr = cityStr + trip.getTripCity() + ",";
                }
                cityStr = cityStr.substring(0, cityStr.length() - 1);

                // 出差城市去重
                Set<String> citySet = new HashSet<>();
                String[] cityArr = cityStr.split(",");
                Collections.addAll(citySet, cityArr);
                tripCityNum = citySet.size();
                Joiner joiner = Joiner.on(",");
                cityStr = joiner.join(citySet);
            }
            summary.setTripCityNum(tripCityNum);
            summary.setTripCity(cityStr);
            summary.setTripDay(tripTotal);

            // 报销
            WorkReimburseSummary reimburse = workReimburseSummaryMapper.selectByWorkCode(workCode);
            summary.setReimburseNum(reimburse != null ? reimburse.getReimburseNum() : 0);

            // 文档阅读
            WorkDocReadSummary docRead = workDocReadSummaryMapper.selectByWorkCode(workCode);
            summary.setDocReadCnt(docRead != null ? docRead.getCnt() : 0);

            // 达道
            WorkLearnSummary learn = workLearnSummaryMapper.selectByWorkCode(workCode);
            summary.setLearnTime(learn != null ? learn.getLearnTime() : BigDecimal.ZERO);
            summary.setFinishTime(learn != null ? learn.getFinishTime() : BigDecimal.ZERO);
            summary.setFinishCourseCnt(learn != null ? learn.getFinishCourseCnt() : 0);
            summary.setObtainScore(learn != null ? learn.getObtainScore() : BigDecimal.ZERO);
            summary.setRequireObtainScore(learn != null ? learn.getRequireObtainScore() : BigDecimal.ZERO);
            summary.setOptionObtainScore(learn != null ? learn.getOptionObtainScore() : BigDecimal.ZERO);
            summary.setLearnMinute(learn != null ? learn.getLearnMinute() : BigDecimal.ZERO);

            workSummaryMapper.insertSelective(summary);
        }
        log.info("initUserWorkSummary结束");
    }

    @Override
    @Transactional
    public void rankWorkSummary() {
        log.info("rankWorkSummary开始");
        List<WorkSummary> summaryList = workSummaryMapper.listAll();
        int sumCount = summaryList.size();
        for (int i = 0; i < summaryList.size(); i++) {
            WorkSummary item = summaryList.get(i);
            log.info("正在排名第" + i + "条数据，员工工号为：" + item.getWorkCode());
            // 流程排名计算
            int flowMoreThan = workSummaryMapper.countFlowTotalMoreThan(item.getFlowTotal());
            BigDecimal flowRank = new BigDecimal(flowMoreThan + 1).multiply(new BigDecimal(100)).divide(new BigDecimal(sumCount), 2, RoundingMode.HALF_UP);
            // 新闻阅读排名计算
            int docMoreThan = workSummaryMapper.countDocReadTotalMoreThan(item.getDocReadCnt());
            BigDecimal docRank = new BigDecimal(docMoreThan + 1).multiply(new BigDecimal(100)).divide(new BigDecimal(sumCount), 2, RoundingMode.HALF_UP);
            // 学习时长排名计算
            int learnMoreThan = workSummaryMapper.countLearnTotalMoreThan(item.getLearnMinute());
            BigDecimal learnRank = new BigDecimal(learnMoreThan + 1).multiply(new BigDecimal(100)).divide(new BigDecimal(sumCount), 2, RoundingMode.HALF_UP);
            // 未休年假占比
            BigDecimal unUsedRatio = BigDecimal.ZERO;
            if (item.getAnnualLeave() > 0){
                unUsedRatio = new BigDecimal(item.getAnnualLeave() - item.getHoliday()).multiply(new BigDecimal(100)).divide(new BigDecimal(item.getAnnualLeave()), 2, RoundingMode.HALF_UP);
            }
            // 出差城市数量排名
            int tripMoreThan = workSummaryMapper.countTripTotalMoreThan(item.getTripCityNum());
            BigDecimal tripRank = new BigDecimal(tripMoreThan + 1).multiply(new BigDecimal(100)).divide(new BigDecimal(sumCount), 2, RoundingMode.HALF_UP);
            // 报销数量排名
            int reimburseMoreThan = workSummaryMapper.countReimburseTotalMoreThan(item.getReimburseNum());
            BigDecimal reimburseRank = new BigDecimal(reimburseMoreThan + 1).multiply(new BigDecimal(100)).divide(new BigDecimal(sumCount), 2, RoundingMode.HALF_UP);

            WorkSummary updateSm = new WorkSummary();
            updateSm.setAnnual(item.getAnnual());
            updateSm.setWorkCode(item.getWorkCode());
            updateSm.setFlowRank(flowRank);
            updateSm.setDocReadRank(docRank);
            updateSm.setLearnRank(learnRank);
            updateSm.setTripRank(tripRank);
            updateSm.setReimburseRank(reimburseRank);
            updateSm.setUnUsedRatio(unUsedRatio);
            workSummaryMapper.updateByPrimaryKeySelective(updateSm);
        }
        log.info("rankWorkSummary结束");
    }
}
